

import 'dart:convert';
import 'dart:math';

import 'package:bt_tool/basic/bt_controller.dart';
import 'package:bt_tool/basic/bt_date_tool.dart';
import 'package:bt_tool/basic/bt_db_tool.dart';
import 'package:bt_tool/basic/bt_http.dart';
import 'package:bt_tool/basic/bt_json_tool.dart';
import 'package:bt_tool/basic/bt_language_tool.dart';
import 'package:bt_tool/basic/bt_log_tool.dart';
import 'package:bt_tool/basic/bt_model.dart';
import 'package:bt_tool/basic/bt_notification_center.dart';
import 'package:bt_tool/basic/bt_router.dart';
import 'package:bt_tool/basic/bt_utils.dart';
import 'package:bt_tool/widget/bt_dialog_widget.dart';
import 'package:bt_tool/widget/bt_form_select_widget.dart';
import 'package:bt_tool/widget/bt_loading_widget.dart';
import 'package:bt_tool/widget/bt_text_field.dart';
import 'package:bt_tool/widget/bt_toast.dart';
import 'package:bt_tool/widget/pcList/bt_pc_list_head_model.dart';
import 'package:bt_tool/widget/pcList/bt_pc_list_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_demo/common/config/app_bridge.dart';
import 'package:flutter_demo/common/config/app_router.dart';
import 'package:flutter_demo/tools/project/project_define.dart';
import 'package:flutter_demo/tools/project/model/project_model.dart';
import 'package:flutter_demo/tools/translate/translate_define.dart';
import 'package:flutter_demo/tools/translate/translate_tool.dart';
import 'package:get/get.dart';
import '../model/translate_content_model.dart';

class TranslateMainController extends BTController{

  int pid = 0;
  ProjectModel? projectModel;
  final Set<LogicalKeyboardKey> _keysPressed = {};
  var dataList = <TranslateContentModel>[];
  // List<String> headList = [];
  TranslateContentModel? lastSelModel;
  var dataStatusList = [
    BTFormSelectModel(-1, "全部".tr, true),
    BTFormSelectModel(0, "未导出".tr, false),
    BTFormSelectModel(1, "已导出".tr, false),
  ].obs;
  var dataStatus = -1;
  final BTTextFieldController textFieldController = BTTextFieldController();
  final ScrollController hozController = ScrollController();
  final BTPcListController pcListController = BTPcListController();
  List<BTPcListHeadModel> headModelList = [];
  var totalDataNum = 0.obs;

  @override
  Future<void> initState() async {
    super.initState();
    pid = routerJsonTool.getInt("id");
    await createTable();
    var dataMapList = await BTDbTool.share().query(ProjectDefine.tableName,where: "id = ?",whereArgs: [pid]);
    if(dataMapList.isNotEmpty){
      projectModel = ProjectModel(dataMapList.first);
      updateWidget();
    }
    HardwareKeyboard.instance.addHandler((event){
      if(event is KeyUpEvent){
        lastSelModel = null;
        _keysPressed.remove(event.logicalKey);
      }else if(event is KeyDownEvent){
        _keysPressed.add(event.logicalKey);
      }

      if(event is KeyDownEvent &&
          _keysPressed.contains(LogicalKeyboardKey.metaLeft) &&
          event.logicalKey == LogicalKeyboardKey.keyA){
        for(var model in dataList){
          model.isSel = true;
        }
        pcListController.refreshAction();
      }

      if(event is KeyDownEvent &&
          _keysPressed.contains(LogicalKeyboardKey.metaLeft) &&
          event.logicalKey == LogicalKeyboardKey.keyD){
        for(var model in dataList){
          model.isSel = false;
        }
        pcListController.refreshAction();
      }

      return false;
    });
    BTNotificationCenter.share().add("createTranslateDataCopy", this);
    await refreshData();
  }

  @override
  void btReceiveNotification(BTNotificationSendModel notificationModel) {
    super.btReceiveNotification(notificationModel);
    if(notificationModel.name == "createTranslateDataCopy"){
      readData();
    }
  }

  readData() async {
    final data = await Clipboard.getData(Clipboard.kTextPlain);
    if (data != null && data.text != null) {
      saveData(data.text);
    }
  }

  refreshData() async {
    if(projectModel == null){
      return;
    }

    if(projectModel!.translateConfig.isEmpty){
      return;
    }

    var columns = projectModel!.translateConfig.replaceAll("-", "").split(",");
    columns.addAll(["key","dataId","isHadExport"]);
    List<dynamic> whereArgs = [projectModel!.id];
    var whereSql = "pid = ?";
    String searchStr = textFieldController.getText();
    if(dataStatus != -1){
      whereSql = "$whereSql and isHadExport = ?";
      whereArgs.add(dataStatus);
    }
    if(searchStr.isNotEmpty){
      whereSql = "$whereSql and key like ?";
      whereArgs.add("%$searchStr%");
    }
    var mapList = await BTDbTool.share().query(TranslateDefine.contentTableName,where: whereSql,whereArgs: whereArgs,orderBy: "createTime DESC",columns: columns);
    bool isNeedUpdate = headModelList.isEmpty;
    var idList = projectModel!.translateConfig.replaceAll("-", "").split(",");
    if(isNeedUpdate){
      BTPcListHeadModel statusHeadModel = BTPcListHeadModel(
        id: TranslateDefine.listStatusKey,
        title: "状态".btTrans,
        width: 100,
      );
      headModelList.add(statusHeadModel);

      BTPcListHeadModel headKeyModel = BTPcListHeadModel(
        id: "key",
        title: "key",
        width: 200,
      );
      headModelList.add(headKeyModel);
      for(var str in idList){
        BTPcListHeadModel headModel = BTPcListHeadModel(
          id: str,
          title: TranslateDefine.baseLanguageMapReverse[str] ?? "",
          width: 200,
        );
        headModelList.add(headModel);
      }
    }
    List<TranslateContentModel> modelList = [];
    for(var map in mapList){
      modelList.add(TranslateContentModel(map));
    }
    dataList.clear();
    dataList.addAll(modelList);
    pcListController.totalDataNum = dataList.length;
    if(isNeedUpdate){
      updateWidget();
    }
    totalDataNum.value = dataList.length;
    if(pcListController.updateCallback != null){
      pcListController.updateCallback!(dataList.length);
    }

  }

  saveData(String? data) async {
    if(projectModel == null){
      BTToast.showToast("项目为空".btTrans);
      return;
    }

    if (data == null || data.isEmpty){
      BTToast.showToast("请输入内容".btTrans);
      return;
    }
    
    var isDataExist = await BTDbTool.share().isDataExist(TranslateDefine.contentTableName,whereSql: "key = ? and pid = ?",arguments: [data,projectModel!.id]);
    if(isDataExist) {
      BTToast.showToast("数据已存在".btTrans);
      AppBridgeTool.createTranslateReapetNotify(data);
      return;
    }
    String motherLanguage = projectModel!.translateKey;
    BTDbTool.share().insertData(TranslateDefine.contentTableName, {
      "pid" : projectModel!.id,
      "key" : data,
      motherLanguage.replaceAll("-", "") : data,
      "createTime" : BTDateTool.currentTimeSeconds(),
    });
    BTToast.showToast("添加成功".btTrans);
    AppBridgeTool.createTranslateSucNotify(data);
    refreshData();
  }

  createTable() async{
    await BTDbTool.share().createTable(TranslateDefine.contentTableName, [
      BTDbFieldModel("dataId", BTModelFieldType.intType,isPrimaryKey: true,isAutoIncrement: true),
      BTDbFieldModel("pid", BTModelFieldType.intType,isNotNull: false),
      BTDbFieldModel("key", BTModelFieldType.stringType,isNotNull: true),
      BTDbFieldModel("en", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("ja", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("ko", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("fr", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("es", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("it", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("de", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("tr", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("ru", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("pt", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("vi", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("id", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("th", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("ms", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("ar", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("zhCN", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("hi", BTModelFieldType.stringType,isNotNull: false),
      BTDbFieldModel("createTime", BTModelFieldType.intType,isNotNull: true,defaultValue: "0"),
      BTDbFieldModel("isHadExport", BTModelFieldType.intType,isNotNull: true,defaultValue: "0"),
    ]);

    // await BTDbTool.share().alertTable(TranslateDefine.contentTableName, [
    //   BTDbFieldModel("hi", BTModelFieldType.stringType,isNotNull: false),
    // ]);
  }

  createClick() async {
    String key = BTUtils.randomString();
    final data = await Clipboard.getData(Clipboard.kTextPlain);
    BTTextFieldController controller = BTTextFieldController(
      textEditingController: TextEditingController(text: data?.text)
    );
    Widget widget = BTAlertInputWidget(
      controller: controller,
      isPcStyle: true,
      clickCallBack: (action){
        BTDialog.dismiss(key: key);
        if(action == BTAlertAction.ok){
          saveData(controller.getText());
        }
      },
    );
    BTDialog.show(widget,key: key);
  }

  Future<void> translateAction(TranslateContentModel model) async {
    await Future.delayed(const Duration(milliseconds: 500));
    var map = <String,String>{};
    bool isNeedTransAgainForEmpty = false;
    BTPcListHeadModel? hiHeadModel;
    for(var headModel in headModelList){
      await translateContent(headModel,model,map);
      if(headModel.id == TranslateDefine.languageKeyHI && map[headModel.id] == null){
        hiHeadModel = headModel;
      }
    }

    if(hiHeadModel != null){
      await translateContent(hiHeadModel, model, map);
    }



    if(map.isNotEmpty){
      model.parse();
      await BTDbTool.share().update(TranslateDefine.contentTableName, map,where: "dataId = ?",whereArgs: [model.dataId]);
    }
  }

  Future<void> translateContent(BTPcListHeadModel headModel,TranslateContentModel model,Map<String,String> map) async {
    var dbKey = headModel.id;
    if(!TranslateDefine.headKeyArray.contains(dbKey) && model.jsonTool.getString(dbKey).isEmpty){
      var targetLanguageResult = dbKey;
      if(targetLanguageResult == "zhCN"){
        targetLanguageResult = "zh-CN";
      }

      if(targetLanguageResult == projectModel!.translateKey){
        map[dbKey] = model.key;
        model.updateMapData(dbKey, model.key);
      }else{
        BTHttpResultItem? result;
        if(targetLanguageResult == TranslateDefine.languageKeyHI){
          //腾讯翻译不支持中文到印地语，取出英文字符串翻译到印度语
          BTJsonTool jsonTool = BTJsonTool(map);
          String enContent = jsonTool.getString(TranslateDefine.languageKeyEN);
          if(enContent.isNotEmpty){
            result = await TranslateTool.translate(enContent, targetLanguageResult,TranslateDefine.languageKeyEN);
          }

        }else{
          result = await TranslateTool.translate(model.key, targetLanguageResult,projectModel!.translateKey);
        }
        if(result == null){
          return;
        }
        if(result.isSuccess()){
          btLogSave("translate ${model.key}-$targetLanguageResult suc");
          BTJsonTool jsonTool = BTJsonTool(result.businessResultItem?.jsonObjData);
          jsonTool.replaceOriJsonBaseOnNow("Response");
          String text = jsonTool.getString("TargetText");
          text = BTUtils.capitalizeFirstIfEnglish(text);
          map[dbKey] = text;
          model.updateMapData(dbKey, text);
        }else{
          btLogSave("translate ${model.key}-$targetLanguageResult fail");
        }
      }
    }
  }

  translateClick() async {
    BTLoading.showLoading();
    for(var model in dataList){
      if(model.isSel){
        await translateAction(model);
      }
    }
    BTLoading.dismiss();
    pcListController.refreshAction();
  }

  configClick(){
    BTRouter.share().pushToUrl(
      routerUrl: AppRouterDefine.translateConfigPage,
      routerParameter: {
        "pid" : projectModel?.id,
        // "dataStr" : projectModel?.translateConfig,
        // "pid" : projectModel?.id,
        // "translateKey" : projectModel?.translateKey,
      },
      callback: (obj,id) async {
        if(id == "saveSuc"){
          var dataMap = await BTDbTool.share().queryMap(ProjectDefine.tableName,where: "id = ?",whereArgs: [pid]);
          projectModel?.reParse(dataMap);
          updateWidget();
          refreshData();
        }
      }
    );
  }

  showKeyMenuView(TranslateContentModel model,Offset position) async {
    final overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
    List<PopupMenuItem> items = [
      PopupMenuItem<TranslateMainMenuAction>(value: TranslateMainMenuAction.translateEmpty, child: Text("翻译空内容".btTrans)),
      PopupMenuItem<TranslateMainMenuAction>(value: TranslateMainMenuAction.setDidExport, child: Text("设置为已导出".btTrans)),
      PopupMenuItem<TranslateMainMenuAction>(value: TranslateMainMenuAction.editKey, child: Text("编辑KEY".btTrans)),
      PopupMenuItem<TranslateMainMenuAction>(value: TranslateMainMenuAction.copyKey, child: Text("复制KEy".btTrans)),
      PopupMenuItem<TranslateMainMenuAction>(value: TranslateMainMenuAction.del, child: Text("删除".btTrans)),
    ];



    await showMenu(
      context: context,
      position: RelativeRect.fromRect(
        Rect.fromLTWH(position.dx, position.dy, 0, 0),
        Offset.zero & overlay.size,
      ),
      items: items,
    ).then((value) async {
      if (value == null) {
        return;
      }
      int id = model.dataId;

      if (value == TranslateMainMenuAction.del){
        await BTDbTool.share().deleteData(TranslateDefine.contentTableName,where: "dataId = ?",whereArgs: [id]);
        BTToast.showToast("删除成功".btTrans);
        dataList.remove(model);
        pcListController.updateAction(dataList.length);
        return;
      }

      if(value == TranslateMainMenuAction.translateEmpty){
        if(projectModel == null){
          BTToast.showToast("项目数据为空".btTrans);
          return;
        }

        if(model.checkIsNeedTranslate(headModelList) == false){
          BTToast.showToast("无数据需要翻译".btTrans);
          return;
        }

        BTLoading.showLoading();
        await translateAction(model);
        BTLoading.dismiss();
        pcListController.refreshAction();
        return;
      }

      if(value == TranslateMainMenuAction.editKey){
        String key = BTUtils.randomString();
        BTTextFieldController controller = BTTextFieldController(
          textEditingController: TextEditingController(text: model.key)
        );
        Widget widget = BTAlertInputWidget(
          title: "编辑KEY".btTrans,
          controller: controller,
          isPcStyle: true,
          clickCallBack: (action) async {
            BTDialog.dismiss(key: key);
            if(action == BTAlertAction.ok){
              var text = controller.getText();
              if(text.isNotEmpty){
                await BTDbTool.share().update(TranslateDefine.contentTableName,{"key" : text},where: "dataId = ?",whereArgs: [id]);
                BTToast.showToast("已更新".btTrans);
                model.key = text;
                pcListController.refreshAction();
              }


            }
          },
        );
        BTDialog.show(widget,key: key);
        return;
      }

      if(value == TranslateMainMenuAction.copyKey){
        Clipboard.setData(ClipboardData(text: model.key));
        BTToast.showToast("已复制到粘贴板".btTrans);
        return;
      }

      if(value == TranslateMainMenuAction.setDidExport){
        await BTDbTool.share().update(TranslateDefine.contentTableName, {"isHadExport" : 1},where: "dataId = ?",whereArgs: [model.dataId]);
        model.isHadExport = 1;
        pcListController.refreshAction();
        return;
      }

    });
  }

  showItemMenuView(TranslateContentModel model,Offset position,String dbKey) async {
    final overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
    List<PopupMenuItem> items = [
      PopupMenuItem<TranslateMainMenuAction>(value: TranslateMainMenuAction.clearTranslate, child: Text("清除".btTrans)),
      PopupMenuItem<TranslateMainMenuAction>(value: TranslateMainMenuAction.editTranslate, child: Text("编辑".btTrans)),
      PopupMenuItem<TranslateMainMenuAction>(value: TranslateMainMenuAction.exportIos, child: Text("导出iOS风格".btTrans)),
      PopupMenuItem<TranslateMainMenuAction>(value: TranslateMainMenuAction.exportJson, child: Text("导出json风格".btTrans)),
    ];

    await showMenu(
      context: context,
      position: RelativeRect.fromRect(
        Rect.fromLTWH(position.dx, position.dy, 0, 0),
        Offset.zero & overlay.size,
      ),
      items: items,
    ).then((value) async {
      doItemMenuAction(model, dbKey, value);
    });
  }

  doItemMenuAction(TranslateContentModel model,String dbKey,dynamic value) async {
    if (value == null) {
      return;
    }
    int id = model.dataId;
    if (value == TranslateMainMenuAction.clearTranslate){
      await BTDbTool.share().update(TranslateDefine.contentTableName, {dbKey : ""},where: "dataId = ?",whereArgs: [id]);
      model.updateMapData(dbKey, "");
      model.parse();
      pcListController.refreshAction();
      BTToast.showToast("已清除".btTrans);
      return;
    }

    if(value == TranslateMainMenuAction.editTranslate){
      String key = BTUtils.randomString();
      BTTextFieldController controller = BTTextFieldController(
          textEditingController: TextEditingController(text: model.jsonTool.getString(dbKey))
      );
      Widget widget = BTAlertInputWidget(
        lineNum: 5,
        title: "编辑翻译内容".btTrans,
        controller: controller,
        isPcStyle: true,
        clickCallBack: (action) async {
          BTDialog.dismiss(key: key);
          if(action == BTAlertAction.ok){
            var text = controller.getText();
            if(text.isNotEmpty){
              await BTDbTool.share().update(TranslateDefine.contentTableName,{dbKey : text},where: "dataId = ?",whereArgs: [id]);
              BTToast.showToast("已更新".btTrans);
              model.updateMapData(dbKey, text);
              model.parse();
              pcListController.refreshAction();
            }
          }
        },
      );
      BTDialog.show(widget,key: key);
      return;
    }

    if(value == TranslateMainMenuAction.exportIos){
      String text =  "\"${model.key}\" = \"${model.jsonTool.getString(dbKey)}\";";
      Clipboard.setData(ClipboardData(text: text));
      BTToast.showToast("已复制到粘贴板".btTrans);
      return;
    }

    if(value == TranslateMainMenuAction.exportJson){
      String text =  "\"${model.key}\" : \"${model.jsonTool.getString(dbKey)}\",";
      Clipboard.setData(ClipboardData(text: text));
      BTToast.showToast("已复制到粘贴板".btTrans);
      return;
    }

  }

  exportSelectData(){
    if(projectModel == null || headModelList.isEmpty){
      return;
    }
    Map<String,String> dataMap = {};
    for(var model in dataList.reversed){
      if(model.isSel){
        for(var headModel in headModelList){
          var key = headModel.id;
          if (!TranslateDefine.headKeyArray.contains(key)){
            String dataStr = dataMap[key] ?? "";
            if(projectModel?.translateExportType.value == TranslateDefaultExportType.ios.iValue){
              if(dataStr.isEmpty){
                dataMap[key] = "\"${model.key}\" = \"${model.jsonTool.getString(key)}\";";
              }else{
                dataMap[key] = "$dataStr\n\"${model.key}\" = \"${model.jsonTool.getString(key)}\";";
              }
            }else{
              if(dataStr.isEmpty){
                dataMap[key] = "{\n\"${model.key}\" : \"${model.jsonTool.getString(key)}\",";
              }else{
                dataMap[key] = "$dataStr\n\"${model.key}\" : \"${model.jsonTool.getString(key)}\",";
              }
            }
          }
          
        }
      }
    }

    if(dataMap.isEmpty){
      BTToast.showToast("请选择需要导出的数据".btTrans);
      return;
    }

    if(projectModel?.translateExportType.value == TranslateDefaultExportType.json.iValue){
      for(var key in dataMap.keys){
        dataMap[key] = "${dataMap[key]!}\n}";
      }
    }

    String firstKey = dataMap.keys.first;
    if(firstKey == projectModel!.translateKey.replaceAll("-", "")){
      var data = dataMap[firstKey];
      dataMap.remove(firstKey);
      dataMap[firstKey] = data!;
    }

    BTRouter.share().pushToUrl(routerUrl: AppRouterDefine.translateResultPage,routerParameter: {
      "dataMap" : dataMap,
    });

    // String resultStr = "";
    // for(var key in dataMap.keys){
    //   String data = dataMap[key]!;
    //   if(resultStr.isEmpty){
    //     resultStr = "$key\n$data";
    //   }else{
    //     resultStr = "$resultStr\n\n$key\n$data";
    //   }
    // }

    // String dialogKey = BTUtils.randomString();
    // BTAlertTextWidget widget = BTAlertTextWidget(
    //   contentWidth: 600,
    //   isCanSelect: true,
    //   contentAlign: TextAlign.start,
    //   title: "翻译结果".btTrans,
    //   contentStr: resultStr,
    //   okStr: "复制".btTrans,
    //   contentHeight: 250,
    //   clickCallBack: (action){
    //     BTDialog.dismiss(key: dialogKey);
    //     if(action == BTAlertAction.ok){
    //       Clipboard.setData(ClipboardData(text: resultStr));
    //       BTToast.showToast("已复制到粘贴板".btTrans);
    //     }
    //   },
    // );
    // BTDialog.show(widget,key: dialogKey);
  }

  changeModelSelectStatus(TranslateContentModel model){
    model.isSel = !model.isSel;
    pcListController.refreshAction();
    if(_keysPressed.contains(LogicalKeyboardKey.metaLeft) && model.isSel){
      if(lastSelModel == null){
        lastSelModel = model;
      }else{
        var nowIndex = dataList.indexOf(model);
        var lastIndex = dataList.indexOf(lastSelModel!);
        if(nowIndex == lastIndex){
          return;
        }

        var startIndex = 0;
        var endIndex = 0;
        if(nowIndex > lastIndex){
          startIndex = lastIndex;
          endIndex = nowIndex;
        }else{
          startIndex = nowIndex;
          endIndex = lastIndex;
        }

        for(var index = startIndex;index<=endIndex;index++){
          dataList[index].isSel = true;
        }
        pcListController.refreshAction();
      }

    }

  }

  setSelectDataToDidExport() async {
    for(var model in dataList){
      if(model.isSel){
        await BTDbTool.share().update(TranslateDefine.contentTableName, {"isHadExport" : 1},where: "dataId = ?",whereArgs: [model.dataId]);
        model.isHadExport = 1;
      }
    }
    refreshData();
  }
}